package com.joymart.user.service;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.joymart.user.model.BusinessRole;
import com.joymart.user.model.CachedUser;
import com.joymart.user.model.User;
import com.joymart.user.repo.BusinessRoleRepository;
import com.joymart.user.repo.UserRepository;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;

@Slf4j
@Component
public class UserCacheManager {

    private LoadingCache<String, CachedUser> userCache;

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private BusinessRoleRepository businessRoleRepository;
    @Autowired
    private UserRestAuthorityService userRestAuthorityService;

    // 初始化缓存配置
    @PostConstruct
    public void init() {

        // 未命中时从数据库加载用户信息
        userCache = Caffeine.newBuilder()
                .maximumSize(100_000)  // 设置最大缓存数量
                .build(this::assembleCachedUser);
        log.info("CachedUserManager initialized with Caffeine cache.");
    }

    // 从缓存中获取用户信息
    public CachedUser get(String userId) {
        return userCache.get(userId);
    }

    // 清理缓存中的用户数据
    public void invalidateUser(String userId) {
        userCache.invalidate(userId);
    }

    public void clear(){
        userCache.invalidateAll();
    }


    private CachedUser assembleCachedUser(String userId) {
        User user = userRepository.findById(userId).orElse(null);

        if(user.isPartyA()){
            List<String> userRestAuthorities = userRestAuthorityService.findByUserId(userId);
            return new CachedUser(user, userRestAuthorities);
        }else {
            List<BusinessRole> businessRoles = new ArrayList<>(businessRoleRepository.getBusinessRoles(userId));
            Collections.sort(businessRoles);
            List<String> downstreamIds = userRepository.getLowerUserIds(userId);
            return new CachedUser(user,businessRoles, downstreamIds);
        }


    }

    /**
     * 向上检索，直到满足条件 或为null
     * @param
     * @return
     */
    public CachedUser upwardSearchUntil(CachedUser srcUser, Predicate<CachedUser> predicate) {
          if(srcUser.getUser().getInvitedBy() == null){
              return null;
          }
          CachedUser parent = this.get(srcUser.getUser().getInvitedBy());
          if(predicate.test(parent)){
              return parent;
          }else {
              return upwardSearchUntil(parent, predicate);
          }
    }


    public CachedUser downwardsSearchUntil(CachedUser srcUser, Predicate<CachedUser> predicate, boolean checkSelf) {
        if(checkSelf && predicate.test(srcUser)){
            return srcUser;
        }
        return downwardsSearchUntil(srcUser, predicate);
    }

    /**
     * 向下检索，直到满足条件（如果有多个满足条件的只返回第一个） 如没有则返回null
     * @param
     * @return
     */
    public CachedUser downwardsSearchUntil(CachedUser srcUser, Predicate<CachedUser> predicate) {

        List<String> downstreamIds = srcUser.getDownstreamIds();

        for (String downstreamId : downstreamIds) {
            CachedUser child = this.get(downstreamId);
            if(predicate.test(child)){
                return child;
            }else{
                CachedUser grandChild = this.downwardsSearchUntil(child, predicate);
                if(grandChild != null){
                    return grandChild;
                }
            }
        }

        return null;

    }



}
